home *** CD-ROM | disk | FTP | other *** search
/ Aminet 16 / Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso / Aminet / misc / emu / QDOS2.lha / QLsource / ROMsrc / MAIN / MAIN_asm
Text File  |  1995-09-11  |  33KB  |  1,742 lines

  1.     SECTION MAIN
  2.  
  3.     INCLUDE '/INC/QDOS_inc'
  4.     INCLUDE '/INC/AMIGA_inc'
  5.     INCLUDE '/INC/AMIGQDOS_inc'
  6.  
  7. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  8. ; MAIN1_asm - Amiga specific patches
  9. ;       - last modified 11/09/95
  10.  
  11. ; These are all the necessary sources required to convert a
  12. ; standard QL specific QDOS ROM, for use on the Amiga computer.
  13.  
  14. ; QDOS-Amiga sources by Rainer Kowallik
  15. ;  ...latest changes by Mark J Swift
  16. ;  ...COPYBACK switches added by SNG
  17.  
  18. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  19. ;extras     equ     1
  20. ;dotrace  equ     1
  21.  
  22. ;  ROM header
  23.  
  24. BASE:
  25.     dc.l    $4AFB0001    ; ROM recognition code
  26.     dc.w    PROC_DEF-BASE    ; add BASIC procs here
  27.     dc.w    ROM_START-BASE
  28.  
  29.     dc.b    0,32
  30.     dc.b    'Amiga-QDOS MAIN o/s hooks v1.40'
  31.     dc.b    $A
  32.  
  33. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  34. ;  start of ROM code
  35.  
  36. ROM_START:
  37.  
  38. ; --------------------------------------------------------------
  39. ;  enter supervisor mode and disable interrupts
  40.  
  41.     trap    #0
  42.  
  43.     ori.w    #$0700,sr    ; disable interrupts
  44.  
  45. ; --------------------------------------------------------------
  46. ;  save register entry values
  47.  
  48.     movem.l    d0-d3/a0-a4/a6,-(a7)
  49.  
  50. ; --------------------------------------------------------------
  51. ;  disable all interrupts and DMA
  52.  
  53.     move.b    #$7F,CIAA_ICR    ; no ints from CIA-A
  54.     move.b    #$7F,CIAB_ICR    ; no ints from CIA-B
  55.     move.w    #$7FFF,INTREQ    ; clear interrupt requests
  56.     move.w    #$7FFF,INTENA    ; disable interrupts
  57.     move.w    #$07FF,DMACON    ; no DMA, no blitter prio'ty
  58.     clr.b    $de0000        ; no slow bus errors
  59.  
  60. ; --------------------------------------------------------------
  61. ;  clear bitplanes and Amiga variables
  62.  
  63.     lea    $10000,a0
  64.     move.w    #$1FFF,d0
  65. CLR_BP:
  66.     clr.l    (a0)+
  67.     dbra    d0,CLR_BP
  68.  
  69.     lea    $18200,a0
  70.     move.w    #$F7F,d0
  71. CLR_AV:
  72.     clr.l    (a0)+
  73.     dbra    d0,CLR_AV
  74.  
  75. ; --------------------------------------------------------------
  76. ;  store amiga vars identification long word
  77.  
  78.     move.w    #(AV_IDENT>>16),AV.IDENT
  79.     move.w    #(AV_IDENT&$FFFF),AV.IDENT+2
  80.  
  81. ;  clear mirror CIA variables
  82.  
  83.     clr.b    AV.CIAA_ICR
  84.     clr.b    AV.CIAB_ICR
  85.     clr.b    AV.CIAA_MSK
  86.     clr.b    AV.CIAB_MSK
  87.  
  88. ; --------------------------------------------------------------
  89. ;  allocate memory for local variables
  90.  
  91.     move.l    #MV_LEN,d1
  92.     moveq    #MT.ALCHP,d0
  93.     moveq    #0,d2
  94.     trap    #1
  95.  
  96.     move.l    a0,AV.MAIV
  97.     move.l    a0,a4
  98.  
  99. ; --------------------------------------------------------------
  100. ;  allocate memory for ROM redirection links
  101.  
  102.     move.l    #RV_LEN,d1
  103.     moveq    #MT.ALCHP,d0
  104.     moveq    #0,d2
  105.     trap    #1
  106.  
  107.     move.l    a0,MV.RVARS(a4)
  108.  
  109. ; --------------------------------------------------------------
  110.     move.l    a7,d0
  111.     andi.l    #$FFFF8000,d0
  112.     move.l    d0,a6        ; address of system vars
  113.  
  114.     suba.l    a0,a0        ; a handy reference point
  115.  
  116.     tst.b    161(a6)
  117.     beq.s    STOVCTRS
  118.  
  119. ; --------------------------------------------------------------
  120. ;  allocate memory and set vector base register (010+)
  121.  
  122.     move.l    #1024,d1
  123.     moveq    #MT.ALCHP,d0
  124.     moveq    #0,d2
  125.     trap    #1
  126.  
  127.     moveq    #47,d0
  128.     suba.l    a1,a1
  129.  
  130. MOVVCTRS:
  131.     move.l    (a1)+,(a0)+
  132.     dbra    d0,MOVVCTRS
  133.  
  134.     move.w    #207,d0
  135.     suba.l    a1,a1
  136.  
  137. CLRVCTRS:
  138.     move.l    12*4(a1),(a0)+
  139.     dbra    d0,CLRVCTRS
  140.  
  141.     lea    -1024(a0),a0
  142.     move.l    4*4(a0),61*4(a0)    ; new illegal instruction?
  143.     dc.w    $4E7B,$8801    ; movec a0,vbr
  144.  
  145. ; --------------------------------------------------------------
  146. ;  Redirect RESET routine
  147.  
  148. STOVCTRS:
  149.     move.l    MV.RVARS(a4),a2
  150.  
  151.     lea    RV.RSETlink(a2),a1
  152.     move.l    a1,AV.RSETlink    ; ptr to 1st link
  153.  
  154.     clr.l    (a1)        ; clear final link
  155.     move.l    $04(a0),$04(a1)    ; address of ROM routine
  156.  
  157.     lea    RSET(pc),a1    ; make redirection routine
  158.     move.l    a1,$04(a0)    ; new exception
  159.  
  160. ; --------------------------------------------------------------
  161. ;  Redirect ILLEGAL interrupt routine
  162.  
  163.     lea    RV.ILLGlink(a2),a1
  164.     move.l    a1,AV.ILLGlink    ; ptr to 1st link
  165.  
  166.     clr.l    (a1)        ; clear final link
  167.     move.l    $60(a0),$04(a1)    ; address of ROM routine
  168.  
  169.     lea    ILLG(pc),a1    ; make redirection routine
  170.     move.l    a1,$60(a0)    ; new exception
  171.  
  172. ; --------------------------------------------------------------
  173. ;  store link to LVL5 interrupt routine
  174.  
  175.     lea    RV.LVL5link(a2),a1
  176.     move.l    a1,AV.LVL5link    ; ptr to 1st link
  177.  
  178.     clr.l    (a1)        ; clear final link
  179.     move.l    $74(a0),$04(a1)    ; address of ROM routine
  180.  
  181. ; --------------------------------------------------------------
  182. ;  store link to LVL7 interrupt routine
  183.  
  184.     lea    RV.LVL7link(a2),a1
  185.     move.l    a1,AV.LVL7link    ; ptr to 1st link
  186.  
  187.     clr.l    (a1)        ; clear final link
  188.     move.l    $7C(a0),$04(a1)    ; address of ROM routine
  189.  
  190. ; --------------------------------------------------------------
  191. ;  Redirect other interrupts through relevant vectors
  192.  
  193.     lea    RV.MAINlink(a2),a1
  194.     move.l    a1,AV.MAINlink    ; ptr to 1st link
  195.  
  196.     clr.l    (a1)        ; clear final link
  197.     move.l    $68(a0),$04(a1)    ; address of ROM routine
  198.  
  199.     lea    MAIN(pc),a1    ; make new exception for...
  200.     move.l    a1,$64(a0)    ; level 1
  201.     move.l    a1,$68(a0)    ; level 2
  202.     move.l    a1,$6C(a0)    ; level 3
  203.     move.l    a1,$70(a0)    ; level 4
  204.     move.l    a1,$74(a0)    ; level 5
  205.     move.l    a1,$78(a0)    ; level 6
  206.     move.l    a1,$7C(a0)    ; level 7
  207.  
  208. ; --------------------------------------------------------------
  209. ;  Redirect TRAP #0 routine
  210.  
  211.     lea    RV.TRP0link(a2),a1
  212.     move.l    a1,AV.TRP0link    ; ptr to 1st link
  213.  
  214.     clr.l    (a1)        ; clear final link
  215.     move.l    $80(a0),$04(a1)    ; address of ROM routine
  216.  
  217.     lea    TRP0(pc),a1    ; make redirection routine
  218.     move.l    a1,$80(a0)    ; new exception
  219.  
  220. ; --------------------------------------------------------------
  221. ;  Redirect TRAP #1 routine
  222.  
  223.     lea    RV.TRP1link(a2),a1
  224.     move.l    a1,AV.TRP1link    ; ptr to 1st link
  225.  
  226.     clr.l    (a1)        ; clear final link
  227.     move.l    $84(a0),$04(a1)    ; address of ROM routine
  228.  
  229.     lea    TRP1(pc),a1    ; make redirection routine
  230.     move.l    a1,$84(a0)    ; new exception
  231.  
  232. ; --------------------------------------------------------------
  233. ;  dislocate original polled task list
  234.  
  235.     move.l    #0,SV_PLIST(a6)    ; pointer to list of polled
  236.                 ; tasks
  237.  
  238. ; --------------------------------------------------------------
  239. ;  link a custom routine onto the RESET routine
  240.  
  241.     lea    AV.RSETlink,a1
  242.     lea    MV.RSETlink(a4),a2
  243.  
  244.     move.l    (a1),(a2)
  245.     move.l    a2,(a1)
  246.  
  247.     lea    MY_RSET(pc),a1
  248.     move.l    a1,$04(a2)
  249.  
  250. ; --------------------------------------------------------------
  251. ;  link a custom routine into level 7 interrupt server
  252.  
  253.     lea    AV.LVL7link,a1
  254.     lea    MV.LVL7link(a4),a2
  255.  
  256.     move.l    (a1),(a2)
  257.     move.l    a2,(a1)
  258.  
  259.     lea    MY_LVL7(pc),a1
  260.     move.l    a1,$04(a2)
  261.  
  262. ; --------------------------------------------------------------
  263. ;  initialise relevant hardware
  264.  
  265.     bsr    INIT_HW
  266.  
  267.     move.b    AV.FLGS1,d0
  268.     andi.b    #%00111111,d0
  269.     move.b    d0,AV.FLGS1    ; allow blitter activity
  270.  
  271. ; --------------------------------------------------------------
  272. ;  restore register entry values
  273.  
  274. ROM_EXIT:
  275.     movem.l    (a7)+,d0-d3/a0-a4/a6
  276.  
  277. ; --------------------------------------------------------------
  278. CHEC_BEGin:
  279.     movem.l    d0/a1/a3,-(a7)
  280.  
  281. ; --------------------------------------------------------------
  282.  
  283.     movem.l    a4-a6,-(a7)
  284.  
  285.     move.l    a7,d0
  286.     andi.l    #$FFFF8000,d0
  287.     move.l    d0,a6        ; address of system vars
  288.  
  289. ; --------------------------------------------------------------
  290. ;  Link unused memory (system memory has to be contiguous), into
  291. ;  common heap. Allocate ranges that do not contain memory as
  292. ;  'used'.
  293.  
  294.     move.l    SV_RAMT(a6),a3    ; don't check memory beyond
  295.     move.l    a3,d0
  296.     add.l    #$00040000-1,d0    ; assume ROMs < 256K and
  297.     andi.l    #$FFFC0000,d0    ; a 256K minimum mem chunk
  298.     move.l    d0,a2        ; probable top of RAM
  299.  
  300.     cmp.l    #$1000000,a6
  301.     bge    ROM_DO
  302.  
  303. ; find last free space in common heap
  304.  
  305.     lea    SV_CHPFR(a6),a5    ; first free space in heap
  306.     subq.l    #4,a5
  307.  
  308.     bra.s    CHPJMP
  309.  
  310. CHPLUP:
  311.     adda.l    d0,a5        ; next free space
  312.  
  313. CHPJMP:
  314.     move.l    4(a5),d0
  315.     bne.s    CHPLUP
  316.  
  317.     move.l    SV_FREE(a6),a4
  318.  
  319. ; link free CHIP RAM into common heap
  320.  
  321.     bsr    chip_ram     ; how much CHIP RAM?
  322.  
  323.     bsr    MEMLINK        ; link memory into common heap
  324.  
  325.     cmp.l    a2,a3
  326.     ble.s    MEMSKIP
  327.  
  328. ; link expansion memory into common heap
  329.  
  330.     lea    $200000,a1
  331.  
  332. ERAM_LUP:
  333.     bsr    expansion_ram    ; how much EXPANSION RAM?
  334.  
  335.     bsr    MEMLINK        ; link memory into common heap
  336.  
  337.     move.l    a2,a1
  338.     adda.l    #$10000,a1    ; next 64K
  339.  
  340.     cmp.l    #$A00000,a1
  341.     blt.s    ERAM_LUP
  342.  
  343.     cmp.l    a1,a3
  344.     ble.s    MEMSKIP
  345.  
  346. ; link RANGER memory into common heap
  347.  
  348.     bsr    ranger_ram
  349.  
  350.     bsr    MEMLINK
  351.  
  352. MEMSKIP:
  353.     clr.l    4(a5)        ; dislocate last block of RAM
  354.                 ; from common heap.
  355.  
  356.     move.l    0(a4),d0     ; length of last block of RAM
  357.     add.l    a4,d0
  358.     move.l    d0,a2        ; calculate maximum RAMTOP
  359.  
  360.     move.l    a4,a1        ; base of free area
  361.  
  362. ; a1 now holds base of free area, a2 max RAM, a3 RAMTOP
  363.  
  364.  
  365. ; find first usable entry in slave table
  366.  
  367.     move.l    a1,d0
  368.     addi.l    #$1FF,d0
  369.     sub.l    a6,d0        ; Slave blocks start at the
  370.     andi.w    #-$200,d0    ; sys vars and are each 512
  371.     lsr.l    #6,d0        ; bytes long.
  372.  
  373. ; invalidate all slave block entries outside system RAM
  374.  
  375.     lea    SV_STACT(a6),a1    ; first address in slave table
  376.     lea    0(a1,d0.l),a4    ; first usable address
  377.  
  378. INI_TBL1:
  379.     clr.l    (a1)+
  380.     cmpa.l    a4,a1
  381.     blt.s    INI_TBL1
  382.  
  383.     move.l    a1,SV_BTPNT(a6)    ; Store most recent block.
  384.  
  385. ROM_DO:
  386.     movem.l    (a7)+,a4-a6
  387.  
  388. ; link in ROMS from RAMTOP until end of memory
  389.  
  390. ROM_LUP:
  391.     bsr    EPROM_LInk
  392.  
  393.     adda.l    #$100,a3
  394.     cmp.l    a3,a2        ; ..until end of memory
  395.     bgt.s    ROM_LUP
  396.  
  397. ; --------------------------------------------------------------
  398. CHECK_EXit:
  399.     movem.l    (a7)+,d0/a1/a3
  400.  
  401. ;  enable interrupts and re-enter user mode
  402.  
  403.     andi.w    #$D8FF,sr
  404.  
  405.     rts
  406.  
  407. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  408. ; find how much CHIP RAM is installed
  409.  
  410. ; on exit:
  411.  
  412. ;   a1=0
  413. ;   a2=CHIP top
  414.  
  415. chip_ram:
  416.     movem.l    d0-d1/a0-a1,-(a7)
  417.  
  418.     suba.l    a1,a1
  419.     move.l    (a1),a0
  420.     clr.l    (a1)
  421.     suba.l    a2,a2
  422.     move.l    #-$D2B4977,d1
  423.     bra.s    LF801E0
  424.  
  425. LF801DE:
  426.     move.l    d0,(a2)
  427.  
  428. LF801E0:
  429.     lea    $4000(a2),a2
  430.  
  431.     cmpa.l    #$200000,a2    ; ...or maximum CHIP RAM
  432.     beq.s    LF801FA
  433.  
  434.     move.l    (a2),d0
  435.     move.l    d1,(a2)
  436.     nop
  437.     cmp.l    (a1),d1
  438.     beq.s    LF801FA
  439.  
  440.     cmp.l    (a2),d1
  441.     beq    LF801DE
  442.  
  443. LF801FA:
  444.     move.l    d0,(a2)
  445.     move.l    a0,(a1)
  446.  
  447.     movem.l    (a7)+,d0-d1/a0-a1
  448.  
  449.     rts
  450.  
  451. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  452. ; find how much EXPANSION RAM is installed
  453.  
  454. ; The machine has not been reset since expansion.library of
  455. ; AmigaDOS initialised the expansion memory. Therefore when you
  456. ; enter    QDOS the expansion RAM should still be mapped in (if
  457. ; there's any installed).
  458.  
  459. ; on entry
  460.  
  461. ;   a1=EXPANSION base
  462.  
  463. ; on exit:
  464.  
  465. ;   a1=EXPANSION base
  466. ;   a2=EXPANSION top
  467.  
  468. expansion_ram:
  469.     movem.l    d1-d2/a0/a4,-(a7)
  470.  
  471.     move.l    a7,a4        ; save for later
  472.  
  473.     dc.w    $2078,$0008    ; move.l  $08.w,a0 (bus err)
  474.     lea    exp_EXIT(pc),a2
  475.     dc.w    $21CA,$0008    ; move.l  a2,$08.w
  476.  
  477.     move.l    a1,a2
  478.  
  479. exp_NEXT:
  480.     move.w    (a2),d2
  481.     moveq    #1,d1
  482.  
  483. exp_CHEK:
  484.     move.w    d1,(a2)
  485.     cmp.w    (a2),d1
  486.     bne.s    exp_EXIT
  487.  
  488.     lsl.w    #1,d1
  489.     bne.s    exp_CHEK
  490.  
  491.     move.w    d2,(a2)
  492.     adda.l    #$10000,a2    ; next 64K
  493.  
  494.     cmpa.l    #$A00000,a2
  495.     blt.s    exp_NEXT     ; ...or max expansion RAM
  496.  
  497. exp_EXIT:
  498.     dc.w    $21C8,$0008    ; move.l  a0,$08.w
  499.  
  500.     move.l    a4,a7        ; tidy up stack
  501.  
  502.     movem.l    (a7)+,d1-d2/a0/a4
  503.     rts
  504.  
  505. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  506. ; find how much RANGER RAM is installed
  507.  
  508. ; on exit:
  509.  
  510. ;   a1=$C00000
  511. ;   a2=RANGER top
  512.  
  513. ranger_ram:
  514.     movem.l    d0-d1/a0/a4,-(a7)
  515.  
  516.     lea    $C00000,a1
  517.     lea    $DC0000,a0
  518.  
  519.     move.l    a1,a2
  520.  
  521.     adda.l    #$40000,a1    ; a1 holds $C40000
  522.  
  523. LF80330:
  524.     move.l    a2,a4
  525.     adda.l    #$40000,a4
  526.  
  527.     move.w    INTENAR,d1    ; store interrupts
  528.     move.w    -$F66(a4),d0    ; store (RAM) contents
  529.  
  530.     move.w    #$7FFF,$9A-$1000(a4)    ; mirror custom chips?
  531.     tst.w    $1C-$1000(a4)
  532.     bne.s    LF80352            ; ...possible RAM
  533.  
  534.     move.w    #$BFFF,$9A-$1000(a4)
  535.     cmpi.w    #$3FFF,$1C-$1000(a4)
  536.     bne.s    LF80352            ; ...possible RAM
  537.  
  538. ; at this point we definitely have a mirror of the custom chips
  539.  
  540. LF8038A:
  541.     move.w    #$7FFF,INTENA    ; disable all interrupts
  542.  
  543.     ori.w    #%1100000000000000,d1    ; enable interrupts
  544.     move.w    d1,INTENA
  545.  
  546.     bra.s    LF80390            ; ...and exit
  547.  
  548. LF80352:
  549.  
  550. ; may be RAM
  551.  
  552.     move.l    #$F2D4,d1
  553.     move.w    d1,-$F66(a4)    ; store test number into RAM
  554.     cmp.w    -$F66(a4),d1
  555.     bne.s    LF80390        ; exit if RAM test failed
  556.  
  557.     move.l    #$B698,d1
  558.     move.w    d1,-$F66(a4)    ; store different test number
  559.     cmp.w    -$F66(a4),d1
  560.     bne.s    LF80390        ; exit if RAM test failed
  561.  
  562. ; definitely RAM - but may be a mirror of $C00000-$C40000
  563.  
  564.     cmpa.l    a1,a4
  565.     beq    LF80384        ; addresses same? not mirror
  566.  
  567.     cmp.w    -$F66(a1),d1    ; mirror of previous RAM?
  568.     bne.s    LF80384        ; no ...must be real RAM
  569.  
  570.     move.l    #$F2D4,d1
  571.     move.w    d1,-$F66(a4)    ; store test number into RAM
  572.  
  573.     cmp.w    -$F66(a1),d1    ; mirror of previous RAM?
  574.     bne.s    LF80384        ; no ...must be real RAM
  575.  
  576. ; at this point, RAM at (a1) has proven to be a mirror of RAM at (a4)
  577.  
  578. LF80380:
  579.     move.w    d0,-$F66(a4)    ; restore RAM contents
  580.     bra    LF80390        ; ...and exit
  581.  
  582. LF80384:
  583.     move.w    d0,-$F66(a4)    ; restore RAM contents
  584.  
  585.     move.l    a4,a2
  586.  
  587.     cmpa.l    a2,a0        ; check against upper bound
  588.     bhi    LF80330
  589.  
  590. LF80390:
  591.     suba.l    #$40000,a1    ; a1 holds $C00000
  592.  
  593.     movem.l    (a7)+,d0-d1/a0/a4
  594.  
  595. LF8039C:
  596.     rts
  597.  
  598. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  599. ; link memory into common heap as 'free' heap.
  600.  
  601. ; a1 holds base, a2 the upper limit of memory range.
  602.  
  603. MEMLINK:
  604.     movem.l    d0-d1/a3,-(a7)
  605.  
  606.     cmp.l    a1,a2        ; memory range valid?
  607.     ble.s    MEMLINKX
  608.  
  609.     cmp.l    a4,a1
  610.     blt.s    MEMLINK2     ; no previous range
  611.  
  612. ; must link the HOLES between memory ranges as 'allocated' heap
  613.  
  614.     move.l    a4,a3        ; find 'gap' between last
  615.     add.l    0(a4),a3     ; free range and this one.
  616.     move.l    a1,d0
  617.     sub.l    a3,d0
  618.     bne.s    MEMLINK1
  619.  
  620. ; no gap between last memory range and this one, so concatenate
  621.  
  622.     movea.l    a4,a1
  623.     bra.s    MEMLINK5
  624.  
  625. MEMLINK1:
  626.     moveq    #16,d1        ; length of header
  627.     sub.l    d1,a3
  628.     add.l    d1,d0
  629.     move.l    d0,0(a3)     ; store a header for memory hole
  630.     clr.l    $4(a3)
  631.     clr.l    $8(a3)
  632.     clr.l    $C(a3)
  633.  
  634.     sub.l    d1,0(a4)     ; reduce length of last range
  635.  
  636. MEMLINK2:
  637.     cmp.l    SV_FREE(a6),a1    ; common heap extended beyond
  638.     bge.s    MEMLINK3     ; lower bound of memory range?
  639.  
  640.     move.l    SV_FREE(a6),a1    ; new lower bound for memory
  641.  
  642. MEMLINK3:
  643.     cmp.l    a4,a1
  644.     bne.s    MEMLINK4
  645.  
  646.     movea.l    a5,a4
  647.  
  648. MEMLINK4:
  649.     move.l    a1,d0
  650.     sub.l    a4,d0        ; store relative pointer from
  651.     move.l    d0,4(a4)     ; previous block
  652.  
  653.     move.l    a4,a5
  654.     move.l    a1,a4
  655.     move.l    a4,SV_FREE(a6)    ; update SV_FREE
  656.  
  657. MEMLINK5:
  658.     move.l    a2,d0
  659.     sub.l    a1,d0        ; find length of memory block
  660.  
  661.     move.l    d0,0(a1)     ; store length
  662.     clr.l    4(a1)        ; zero pointer to next free block
  663.     clr.l    $8(a1)        ; owner
  664.     clr.l    $C(a1)        ; location to set/clr when removed
  665.  
  666. MEMLINKX:
  667.     movem.l    (a7)+,d0-d1/a3
  668.  
  669.     rts
  670.  
  671. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  672. ;  Subroutine to check for EPROMs and link them in.
  673. ;  Enter in supervisor mode with interrupts disabled.
  674. ;
  675. ;  Entry:
  676. ;    a0 channel ID for messages
  677. ;    a3 start address to check
  678.  
  679. EPROM_LInk:
  680.  
  681.     movem.l    d0-d3/a0-a3,-(a7)
  682.  
  683.     andi.w    #$D8FF,sr    ; enable ints & enter User
  684.                 ; mode
  685.     CMPI.W    #$4AFB,(A3)
  686.     BNE.S    EPROM_EXit
  687.  
  688.     CMPI.W    #$0001,2(A3)
  689.     BNE.S    EPROM_EXit
  690.  
  691.     LEA    8(A3),A1     ; Eprom copyright
  692.     MOVE.W    $D0,A2        ; UT.MTEXT
  693.     JSR    (A2)
  694.  
  695.     MOVE.W    4(A3),D0     ; any Basic extensions ?
  696.     BEQ.S    EPROM_INit
  697.  
  698.     LEA    0(A3,D0.W),A1
  699.     MOVE.W    $110,A2        ; BP.INIT
  700.     JSR    (A2)
  701.  
  702. EPROM_INit:
  703.     MOVE.W    6(A3),D0     ; initialization procedure
  704.     BEQ.S    EPROM_EXit
  705.  
  706.     JSR    0(A3,D0.W)    ; routine must not corrupt
  707.                 ; output channel (a0) or start
  708.                 ; address (a3) and must return
  709.                 ; whilst in USER mode
  710.  
  711. EPROM_EXit:
  712.     trap    #0        ; enter supervisor mode
  713.     ori.w    #$0700,sr    ; disable interrupts
  714.  
  715.     movem.l    (a7)+,d0-d3/a0-a3
  716.  
  717.     rts
  718.  
  719. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  720. ;  Redirection routine for Illegal Interrupt
  721.  
  722. ILLG:
  723.     move.w    #$7FFF,INTREQ    ; clear interrupt request
  724.     move.w    #MAGENTA,COLOR00    ; Signal bad interrupt
  725.  
  726.     subq.l    #4,a7
  727.     movem.l    a3,-(a7)
  728.     move.l    AV.ILLGlink,a3
  729.     move.l    4(a3),4(a7)
  730.     movem.l    (a7)+,a3     ; address of next routine
  731.     rts
  732.  
  733. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  734. ;  Custom interrupt server for main 50Hz & external.interrupts
  735.  
  736. MAIN:
  737.     ori.w    #$0700,sr    ; disable further interrupts
  738.     movem.l    d7/a5/a6,-(a7)
  739.  
  740.     movea.l    a7,a5
  741.     move.l    a7,d7
  742.     andi.l    #$FFFF8000,d7
  743.     move.l    d7,a6        ; address of system vars
  744.  
  745.     move.w    INTENAR,d7
  746.     btst    #5,d7        ; 50Hz ints enabled?
  747.     beq.s    EXTRN_INT    ; no, must be another.
  748.  
  749.     move.w    INTREQR,d7    ; read interrupt request reg
  750.     btst    #5,d7        ; 50Hz interrupt?
  751.     bne.s    FRAME_INT
  752.  
  753. ; --------------------------------------------------------------
  754. ;  Let external interrupt server handle it
  755. ;  NOTE every driver MUST clear the relevant interrupt request!
  756.  
  757. EXTRN_INT:
  758.     move.b    #%00010000,PC_INTR ; signal external interrupt
  759.                  ; in QL hardware
  760.  
  761.     bra.s    MAINX
  762.  
  763. ; --------------------------------------------------------------
  764. ;  server for 50 Hz vertical blank interrupt
  765.  
  766. FRAME_INT:
  767.     move.w    #%0000000000100000,INTREQ ; clear interrupts
  768.  
  769.     move.b    #%00001000,PC_INTR ; signal 50Hz interrupt
  770.                  ; in QL hardware
  771.  
  772. MAINX:
  773.     movem.l    (a7)+,d7/a5/a6
  774.  
  775.     subq.l    #4,a7
  776.     movem.l    a3,-(a7)
  777.     move.l    AV.MAINlink,a3
  778.     move.l    4(a3),4(a7)    ; address of next routine
  779.     movem.l    (a7)+,a3
  780.     rts
  781.  
  782. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  783. ;  Redirect RESET routine through table
  784.  
  785. RSET:
  786.     ori.w    #$0700,sr    ; disable further interrupts
  787.  
  788.     move.b    #$7F,CIAA_ICR    ; no ints from CIA-A
  789.     move.b    #$7F,CIAB_ICR    ; no ints from CIA-B
  790.     move.w    #$7FFF,INTREQ    ; clear interrupt requests
  791.     move.w    #$7FFF,INTENA    ; disable interrupts
  792.     move.w    #$07FF,DMACON    ; no DMA, no blitter prio'ty
  793.  
  794.     subq.l    #4,a7
  795.     movem.l    a3,-(a7)
  796.     move.l    AV.RSETlink,a3
  797.     move.l    4(a3),4(a7)
  798.     movem.l    (a7)+,a3     ; address of next routine
  799.     rts
  800.  
  801. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  802. ;  Redirection routine for Trap #0
  803.  
  804. TRP0:
  805.     move.w    (a7),AV.SR    ; save status register
  806.  
  807.     subq.l    #4,a7
  808.     movem.l    a3,-(a7)
  809.     move.l    AV.TRP0link,a3
  810.     move.l    4(a3),4(a7)    ; address of next routine
  811.     movem.l    (a7)+,a3
  812.  
  813.     ifd    dotrace
  814.  
  815.     btst    #7,4(a7)     ; were we in trace mode?
  816.     beq.s    TRP0X
  817.  
  818.     ori.w    #$8000,sr    ; ...yup, trace back on.
  819.  
  820. TRP0X:
  821.     endif
  822.     rts
  823.  
  824. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  825. ;  Redirection routine for Trap #1
  826.  
  827. TRP1:
  828.     subq.l    #4,a7
  829.     movem.l    a3,-(a7)
  830.     move.l    AV.TRP1link,a3
  831.     move.l    4(a3),4(a7)    ; address of next routine
  832.     movem.l    (a7)+,a3
  833.  
  834.     ifd    dotrace
  835.     btst    #7,4(a7)     ; were we in trace mode?
  836.     beq.s    TRP1X
  837.     ori.w    #$8000,sr    ; ...yup, trace back on.
  838.     endif
  839.  
  840. TRP1X:
  841.     rts
  842.  
  843. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  844. ;  enable relevant interrupts/DMA
  845.  
  846. INIT_HW:
  847.     movem.l    d0,-(a7)
  848.  
  849.     move.w    #%1100000000100000,INTENA ; enable 50Hz int
  850.  
  851.     movem.l    (a7)+,d0
  852.     rts
  853.  
  854. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  855. ;  Custom RESET routine to put back all vectors & reset computer
  856.  
  857. MY_RSET:
  858.     movem.l    d0/a0-a3/a6,-(a7)
  859.  
  860.     suba.l    a0,a0        ; a handy reference
  861.  
  862.     move.l    a7,d0
  863.     andi.l    #$FFFF8000,d0
  864.     move.l    d0,a6        ; address of system vars
  865.  
  866.     tst.b    161(a6)
  867.     beq.s    MY_RSET1
  868.  
  869.     dc.w    $4E7A,$8801    ; movec vbr,a0
  870.  
  871. MY_RSET1:
  872.     move.l    AV.MAIV,a3
  873.     move.l    MV.RVARS(a3),a2
  874.  
  875.     move.l    RV.RSET(a2),$04(a0)
  876.     move.l    RV.ILLG(a2),$60(a0) ; level 0
  877.     move.l    RV.LVL5(a2),$74(a0) ; level 5
  878.     move.l    RV.LVL7(a2),$7C(a0) ; level 7
  879.     move.l    RV.ILLG(a2),$64(a0) ; level 1
  880.     move.l    RV.ILLG(a2),$6C(a0) ; level 3
  881.     move.l    RV.ILLG(a2),$70(a0) ; level 4
  882.     move.l    RV.ILLG(a2),$78(a0) ; level 6
  883.     move.l    RV.MAIN(a2),$68(a0) ; level 2
  884.     move.l    RV.TRP0(a2),$80(a0)
  885.     move.l    RV.TRP1(a2),$84(a0)
  886.  
  887. MY_RSET2:
  888.     movem.l    (a7)+,d0/a0-a3/a6
  889.  
  890.     subq.l    #4,a7
  891.     movem.l    a3,-(a7)
  892.     move.l    AV.MAIV,a3
  893.     move.l    MV.RSETlink(a3),a3
  894.     move.l    4(a3),4(a7)    ; address of next routine
  895.     movem.l    (a7)+,a3
  896.  
  897.     rts
  898.  
  899. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  900. ;  Custom LVL7 routine to initialise hardware
  901.  
  902. MY_LVL7:
  903.     bsr    INIT_HW
  904.  
  905.     subq.l    #4,a7
  906.     movem.l    a3,-(a7)
  907.     move.l    AV.MAIV,a3
  908.     move.l    MV.LVL7link(a3),a3
  909.     move.l    4(a3),4(a7)    ; address of next routine
  910.     movem.l    (a7)+,a3
  911.  
  912.     rts
  913.  
  914. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  915. ;    get attn flags for processor.
  916.  
  917. GET_ATTN:
  918.     movem.l    d0/a6,-(a7)
  919.  
  920.     move.l    a7,d1        ; Calculate start of
  921.     andi.w    #-$8000,d1    ; system variables
  922.     move.l    d1,a6
  923.     move.w    SV_IDENT+2(a6),d1 ; get attn flags
  924.  
  925.     movem.l    (a7)+,d0/a6
  926.     rts
  927.  
  928. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  929. ;  set bits in cacr d0=bits to set d1=bits to clear/alter
  930. ; This assumes 030 control register bits reworks them for 040
  931.  
  932. L0000C8E:
  933.     movem.l    d2-d4,-(a7)
  934.  
  935.     moveq    #$0,d3
  936.  
  937.     exg    d1,d4
  938.     bsr    GET_ATTN
  939.     exg    d1,d4
  940.  
  941.     btst    #$1,d4        ; exit if not at least '020
  942.     beq.s    L0000CAE
  943.  
  944.     and.l    d1,d0
  945.     or.w    #$808,d0     ; signal always clear caches
  946.     not.l    d1
  947.  
  948. L0000CB6:
  949.     ori    #$700,sr ; DODGY? Not restored later
  950.     dc.w    $4E7A,$2002    ; movec    cacr,d2
  951.     btst    #$3,d4
  952.     beq.s    L0000CD0     ; skip if not '040
  953. ;
  954. ; Attempts to convert 040 CACR to 030 form;
  955. ;
  956.  
  957.     move.l    d2,d3
  958.     andi.l    #$7FFF0000,d3    ; keep '060 bits...
  959.  
  960.                 ; mimick ED & EI
  961.  
  962.     swap    d2        ;        8000 8000
  963.     ror.w    #8,d2        ;        8000 0080
  964.     rol.l    #1,d2        ;        0000 0101
  965.     andi.w    #$0101,d2    ; ...only relevant bits
  966.  
  967.     move.w    d2,d3        ; mimick DBE & IBE
  968.     rol.w    #4,d3        ;        0000 1010
  969.     or.l    d3,d2        ;        0000 1111
  970.  
  971. L0000CD0:
  972.     move.l    d2,d3        ; cache register to d3
  973.     and.l    d1,d2        ; mask off changed bits
  974.     or.l    d0,d2        ; or in set bits
  975.     btst    #$3,d4
  976.     beq.s    L0000CEC     ; skip if not '040
  977.  
  978.                 ;        0000 0101
  979.     ror.l    #1,d2        ;        8000 0080
  980.     rol.w    #8,d2        ;        8000 8000
  981.     and.l    #$80008000,d2    ;
  982.  
  983.     swap    d3
  984.     or.w    d3,d2        ; keep '060 bits...
  985.     swap    d3
  986.     swap    d2        ;        8000 8000
  987.  
  988.     nop
  989.     dc.w    $F4F8        ; CPUSHA ic/dc ('040 only)
  990.                 ; update memory from caches
  991.  
  992. L0000CEC:
  993.     nop
  994.     dc.w    $4E7B,$2002    ; movec    d2,cacr
  995.     nop
  996.  
  997. L0000CAE:
  998.     move.l    d3,d0        ; return old bits in d0
  999.  
  1000.     movem.l    (a7)+,d2-d4
  1001.     rts
  1002.  
  1003. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1004. ;  BASIC extensions specific to AMIGA QDOS
  1005.  
  1006. PROC_DEF:
  1007.     ifd    extras
  1008.  
  1009.     dc.w    28
  1010.     dc.w    B_BL_OFF-*
  1011.     dc.b    8,'BLIT_OFF',0
  1012.     dc.w    B_BL_ON-*
  1013.     dc.b    7,'BLIT_ON'
  1014.     dc.w    RESET_RANGE-*
  1015.     dc.b    13,'RESET_EXTENTS'
  1016.     dc.w    RESET_TOP-*
  1017.     dc.b    9,'RESET_TOP'
  1018.     dc.w    RESET_SV-*
  1019.     dc.b    8,'RESET_SV',0
  1020.     dc.w    B_INTEN-*
  1021.     dc.b    6,'INTENA',0
  1022.     dc.w    B_INTRQ-*
  1023.     dc.b    6,'INTREQ',0
  1024.     dc.w    B_DMACN-*
  1025.     dc.b    6,'DMACON',0
  1026.     dc.w    DCACHE_ON-*
  1027.     dc.b    9,'DCACHE_ON'
  1028.     dc.w    DCACHE_OFF-*
  1029.     dc.b    10,'DCACHE_OFF',0
  1030.     dc.w    ICACHE_ON-*
  1031.     dc.b    9,'ICACHE_ON'
  1032.     dc.w    ICACHE_OFF-*
  1033.     dc.b    10,'ICACHE_OFF',0
  1034.  
  1035.         dc.w    COPYBACK_ON-*        ; ** SNG **
  1036.         dc.b    11,'COPYBACK_ON'
  1037.         dc.w    COPYBACK_OFF-*
  1038.         dc.b    12,'COPYBACK_OFF',0
  1039.     dc.w    0
  1040.  
  1041.     dc.w    13
  1042.     dc.w    B_INTENR-*
  1043.     dc.b    7,'INTENAR'
  1044.     dc.w    B_INTRQR-*
  1045.     dc.b    7,'INTREQR'
  1046.     dc.w    B_DMACNR-*
  1047.     dc.b    7,'DMACONR'
  1048.     dc.w    B_CHIP-*
  1049.     dc.b    4,'CHIP',0
  1050.     dc.w    B_EXPANSION-*
  1051.     dc.b    9,'EXPANSION'
  1052.     dc.w    B_RANGER-*
  1053.     dc.b    6,'RANGER',0
  1054.     dc.w    DMODE-*
  1055.     dc.b    5,'DMODE'
  1056.     dc.w    CACHE_REG-*
  1057.     dc.b    9,'CACHE_REG'
  1058.  
  1059.     dc.w    0
  1060.  
  1061.     endc
  1062.  
  1063.     ifnd    extras
  1064.  
  1065.     dc.w    22
  1066.     dc.w    B_BL_OFF-*
  1067.     dc.b    8,'BLIT_OFF',0
  1068.     dc.w    B_BL_ON-*
  1069.     dc.b    7,'BLIT_ON'
  1070.     dc.w    RESET_RANGE-*
  1071.     dc.b    13,'RESET_EXTENTS'
  1072.     dc.w    RESET_TOP-*
  1073.     dc.b    9,'RESET_TOP'
  1074.     dc.w    RESET_SV-*
  1075.     dc.b    8,'RESET_SV',0
  1076.     dc.w    DCACHE_ON-*
  1077.     dc.b    9,'DCACHE_ON'
  1078.     dc.w    DCACHE_OFF-*
  1079.     dc.b    10,'DCACHE_OFF',0
  1080.     dc.w    ICACHE_ON-*
  1081.     dc.b    9,'ICACHE_ON'
  1082.     dc.w    ICACHE_OFF-*
  1083.     dc.b    10,'ICACHE_OFF',0
  1084.  
  1085.     dc.w    COPYBACK_ON-*        ; ** SNG **
  1086.     dc.b    11,'COPYBACK_ON'
  1087.     dc.w    COPYBACK_OFF-*
  1088.     dc.b    12,'COPYBACK_OFF',0
  1089.     dc.w    0
  1090.  
  1091.     dc.w    3
  1092.     dc.w    DMODE-*
  1093.     dc.b    5,'DMODE'
  1094.     dc.w    CACHE_REG-*
  1095.     dc.b    9,'CACHE_REG'
  1096.  
  1097.     dc.w    0
  1098.  
  1099.     endc
  1100.  
  1101. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1102. ;  BASIC extensions specific to AMIGA QDOS
  1103.  
  1104.     ifd    extras
  1105.  
  1106. B_INTEN:
  1107.     bsr    FETCH_W
  1108.     bne.s    B_INTENX
  1109.  
  1110.     cmp.l    a3,a5
  1111.     bne    RPRT_BP
  1112.  
  1113.     move.w    d1,INTENA
  1114.     moveq    #0,d0
  1115.  
  1116. B_INTENX:
  1117.     rts
  1118.  
  1119. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1120. B_INTRQ:
  1121.     bsr    FETCH_W
  1122.     bne.s    B_INTRQX
  1123.  
  1124.     cmp.l    a3,a5
  1125.     bne    RPRT_BP
  1126.  
  1127.     move.w    d1,INTREQ
  1128.     moveq    #0,d0
  1129.  
  1130. B_INTRQX:
  1131.     rts
  1132.  
  1133. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1134. B_DMACN:
  1135.     bsr    FETCH_W
  1136.     bne.s    B_DMACNX
  1137.  
  1138.     cmp.l    a3,a5
  1139.     bne    RPRT_BP
  1140.  
  1141.     move.w    d1,DMACON
  1142.     moveq    #0,d0
  1143.  
  1144. B_DMACNX:
  1145.     rts
  1146.  
  1147.     endc
  1148.  
  1149. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1150. ;  request stop blitter
  1151.  
  1152. B_BL_OFF:
  1153.  
  1154.     bset    #7,AV.FLGS1    ; request blit disable
  1155.     moveq    #0,d0
  1156.  
  1157.     rts
  1158.  
  1159. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1160. ;  request restart blitter
  1161.  
  1162. B_BL_ON:
  1163.  
  1164.     bclr    #7,AV.FLGS1    ; clear blit disable
  1165.     moveq    #0,d0
  1166.  
  1167.     rts
  1168.  
  1169. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1170. RESET_RANGE:
  1171.     bsr    FETCH_L
  1172.     bne.s    RESET_RNGXIT
  1173.     move.l    d1,d6        ; RAMTOP 'from' address
  1174.  
  1175.     bsr    FETCH_L
  1176.     bne.s    RESET_RNGXIT
  1177.     move.l    d1,d7        : RAMTOP 'to' address
  1178.  
  1179.     bsr    FETCH_L
  1180.     bne.s    RESET_RNGXIT
  1181.     move.l    d1,a5        : new SV address
  1182.  
  1183.     move.l    d6,a3
  1184.     move.l    d7,a4
  1185.  
  1186.     trap    #0        ; enter supervisor mode
  1187.     ori.w    #$0700,sr    ; disable interrupts
  1188.  
  1189.     bsr    SYSRANGE
  1190.  
  1191.     bsr    RNGCHK
  1192.     bne.s    RESET_RNGX
  1193.  
  1194.     bsr    SVCHK
  1195.     bne.s    RESET_RNGX
  1196.  
  1197.     bsr    RNGNEW
  1198.     bsr    SVNEW
  1199.  
  1200.     bra    RESET_SV1
  1201.  
  1202. RESET_RNGX:
  1203.     andi.w    #$D8FF,sr    ; user mode, ints on
  1204.  
  1205. RESET_RNGXIT:
  1206.     rts            ; return error
  1207.  
  1208.  
  1209.  
  1210. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1211. RESET_TOP:
  1212.     bsr    FETCH_L
  1213.     bne.s    RESET_TOPXIT
  1214.     move.l    d1,d6        ; ROMTOP 'from' address
  1215.  
  1216.     bsr    FETCH_L
  1217.     bne.s    RESET_TOPXIT
  1218.     move.l    d1,a4        : ROMTOP 'to' address
  1219.  
  1220.     move.l    d6,a3
  1221.  
  1222.     trap    #0        ; enter supervisor mode
  1223.     ori.w    #$0700,sr    ; disable interrupts
  1224.  
  1225.     bsr    SYSRANGE
  1226.     move.l    a2,a5
  1227.  
  1228.     bsr    RNGCHK
  1229.     bne.s    RESET_TOPX
  1230.  
  1231.     bsr    RNGNEW
  1232.  
  1233.     bra.s    RESET_SV1
  1234.  
  1235. RESET_TOPX:
  1236.     andi.w    #$D8FF,sr    ; user mode, ints on
  1237.  
  1238. RESET_TOPXIT:
  1239.     rts            ; return error
  1240.  
  1241. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1242. RESET_SV:
  1243.     bsr    FETCH_L
  1244.     bne.s    RESET_SVXIT
  1245.     move.l    d1,a5        ; new SV address
  1246.  
  1247.     trap    #0        ; enter supervisor mode
  1248.     ori.w    #$0700,sr    ; disable interrupts
  1249.  
  1250.     bsr    SYSRANGE
  1251.     move.l    a0,a1
  1252.  
  1253.     bsr    SVCHK
  1254.     bne.s    RESET_SVX
  1255.  
  1256.     bsr    SVNEW
  1257.  
  1258. RESET_SV1:
  1259.     move.l    $0,a7        ; reset supervisor stack
  1260.  
  1261.     move.l    a7,d0
  1262.     andi.l    #$FFFF8000,d0
  1263.     move.l    d0,a6
  1264.  
  1265.     suba.l    a0,a0
  1266.  
  1267.     tst.b    161(a6)        ; skip if not 010+
  1268.     beq.s    RESET_SV2
  1269.  
  1270.     dc.w    $4E7A,$8801    ; movec vbr,a0
  1271.  
  1272. RESET_SV2:
  1273.     move.l    $4(a0),-(a7)    ; jump to reset routine
  1274.     rts
  1275.  
  1276. RESET_SVX:
  1277.     andi.w    #$D8FF,sr    ; user mode, ints on
  1278.  
  1279. RESET_SVXIT:
  1280.     rts            ; return error
  1281.  
  1282. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1283. RNGNEW:
  1284.     move.l    a1,SV_RAMT(a2)    ; new RAMTOP
  1285.  
  1286.     cmp.l    a3,a4
  1287.     bgt.s    MDN_TST
  1288.     blt.s    MUP_TST
  1289.     bra    RNGNEW_XIT
  1290.  
  1291. MUP_LUP:
  1292.     move.l    (a0),(a1)+    ; ...move
  1293.     clr.l    (a0)+        ; ...and clear
  1294.  
  1295. MUP_TST:
  1296.     cmp.l    a3,a0        ; until end
  1297.     blt.s    MUP_LUP
  1298.  
  1299.     bra.s    RNGNEW_XIT
  1300.  
  1301. MDN_LUP:
  1302.     move.l    -(a3),-(a4)    ; ...move
  1303.     clr.l    (a3)        ; ...and clear
  1304.  
  1305. MDN_TST:
  1306.     cmp.l    a3,a0        ; until end
  1307.     blt.s    MDN_LUP
  1308.  
  1309. RNGNEW_XIT:
  1310.     rts
  1311.  
  1312. RNGCHK:
  1313.     move.l    a0,d1        ; current RAMTOP
  1314.     sub.l    a3,d1        ; ROMTOP 'from'
  1315.     bgt.s    RNGCHK_BP    ; invalid?
  1316.  
  1317.     add.l    a4,d1
  1318.     move.l    d1,a1        ; possible new RAMTOP
  1319.  
  1320.     cmp.l    a5,a1
  1321.     ble.s    RNGCHK_BP    ; invalid 'to' addr
  1322.  
  1323.     moveq    #ERR.OK,d0
  1324.     bra.s    RNGCHK_XIT
  1325.  
  1326. RNGCHK_BP:
  1327.     moveq    #ERR.BP,d0
  1328.  
  1329. RNGCHK_XIT:
  1330.     tst.l    d0
  1331.     rts
  1332.  
  1333. SVNEW:
  1334.     move.l    (a2),(a5)        ; QDOS sysvars ID
  1335.     move.l    SV_RAMT(a2),SV_RAMT(a5)    ; RAMTOP
  1336.     lea    $480(a5),a6
  1337.     move.l    a6,$0            ; new sys stack
  1338.     rts
  1339.  
  1340. SVCHK:
  1341.     move.l    a5,d1
  1342.     andi.w    #$7FFF,d1    ; must be on 32K boundary
  1343.     bne.s    SVCHK_BP
  1344.  
  1345.     cmp.l    #$28000,a5
  1346.     blt.s    SVCHK_BP
  1347.  
  1348.     cmp.l    a2,a5        ; no change?
  1349.     beq.s    SVCHK_BP
  1350.  
  1351.     cmp.l    a1,a5        ; beyond RAMTOP?
  1352.     bge.s    SVCHK_BP
  1353.  
  1354.     moveq    #ERR.OK,d0    ; ev'rythin' fine
  1355.     bra.s    SVCHK_XIT
  1356.  
  1357. SVCHK_BP:
  1358.     moveq    #ERR.BP,d0
  1359.  
  1360. SVCHK_XIT:
  1361.     tst.l    d0
  1362.     rts
  1363.  
  1364. SYSRANGE:
  1365.     move.l    a7,d1
  1366.     andi.l    #$FFFF8000,d1
  1367.     move.l    d1,a2        ; address of system vars
  1368.  
  1369.     move.l    SV_RAMT(a2),a0    ; RAMTOP
  1370.  
  1371.     rts
  1372.  
  1373. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1374.  
  1375. DCACHE_ON:
  1376.     cmp.l    a3,a5
  1377.     bne    RPRT_BP
  1378.  
  1379.     trap    #0        ; sv mode
  1380.     move.l    #$0100,d0
  1381.     move.l    #$0100,d1
  1382.     bsr    L0000C8E
  1383.     andi.w    #$D8FF,sr    ; ints on & user mode
  1384.     moveq    #0,d0        ; no errors
  1385.     rts
  1386.  
  1387. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1388. DCACHE_OFF:
  1389.     cmp.l    a3,a5
  1390.     bne    RPRT_BP
  1391.  
  1392.     trap    #0        ; sv mode
  1393.     moveq    #$0,d0
  1394.     move.l    #$0100,d1
  1395.     bsr    L0000C8E
  1396.     andi.w    #$D8FF,sr    ; ints on & user mode
  1397.     moveq    #0,d0        ; no errors
  1398.     rts
  1399.  
  1400. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1401. ICACHE_ON:
  1402.     cmp.l    a3,a5
  1403.     bne    RPRT_BP
  1404.  
  1405.     trap    #0        ; sv mode
  1406.     moveq    #$1,d0
  1407.     moveq    #$1,d1
  1408.     bsr    L0000C8E
  1409.     andi.w    #$D8FF,sr    ; ints on & user mode
  1410.     moveq    #0,d0        ; no errors
  1411.     rts
  1412.  
  1413. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1414. ICACHE_OFF:
  1415.     cmp.l    a3,a5
  1416.     bne    RPRT_BP
  1417.  
  1418.     trap    #0        ; sv mode
  1419.     moveq    #$0,d0
  1420.     moveq    #$1,d1
  1421.     bsr    L0000C8E
  1422.     andi.w    #$D8FF,sr    ; ints on & user mode
  1423.     moveq    #0,d0        ; no errors
  1424.     rts
  1425.  
  1426. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1427. CACHE_REG:
  1428.     cmp.l    a3,a5
  1429.     bne    RPRT_BP
  1430.  
  1431.     moveq    #0,d0        ; MT.INF
  1432.     trap    #1
  1433.     move.b    161(a0),d0
  1434.     cmp.b    #10,d0
  1435.     bcs.s    RPRT_NI
  1436.  
  1437.     trap    #0        ; sv mode
  1438.     ori    #$700,sr
  1439.     dc.w    $4E7A,$2002    ; movec    cacr,d2
  1440.     andi.w    #$D8FF,sr    ; ints on & user mode
  1441.     move.l    d2,d1
  1442.     bra    RET_L
  1443.  
  1444. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1445. ; Copyback controls by SNG, June 1995
  1446.  
  1447. COPYBACK_ON:
  1448.     cmp.l    a3,a5
  1449.     bne    RPRT_BP
  1450.  
  1451.     moveq    #0,d0        ; MT.INF
  1452.     trap    #1
  1453.     move.b    161(a0),d0
  1454.     cmp.b    #40,d0
  1455.     bcs.s    RPRT_NI
  1456.  
  1457.     trap    #0        ; Supervisor mode
  1458.     ori.w    #$700,sr
  1459.     move.l    #$0000C000,d1    ; Write Through to Chip memory
  1460.     dc.w    $4E7B,$1006    ; movec d1,(006) DTT0
  1461. ;
  1462. ; If TTU/ATU settings clash, DTT0 takes priority over DTT1
  1463. ;
  1464.     move.l    #$00FFC020,d1    ; Copyback on all memory
  1465.     dc.w    $4E7B,$1007    ; movec d1,(007) DTT1
  1466.     andi.w    #$D8FF,sr    ; ints on & user mode
  1467.     moveq    #0,d0
  1468.     rts
  1469.  
  1470. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1471.  
  1472. COPYBACK_OFF:
  1473.     cmp.l    a3,a5
  1474.     bne    RPRT_BP
  1475.     moveq    #0,d0        ; MT.INF
  1476.     trap    #1
  1477.     move.b    161(a0),d0
  1478.     cmp.b    #40,d0
  1479.     bcc.s    ATLEAST040
  1480. RPRT_NI:
  1481.     moveq    #ERR.NI,d0
  1482.     rts
  1483.  
  1484. ATLEAST040:
  1485.  
  1486.     trap    #0        ; Supervisor mode
  1487.     ori.w    #$700,sr
  1488.  
  1489.     dc.w    $F478        ; CPUSHA dc ('040 plus)
  1490.     move.l    #$00FF0000,d1    ; ATU off pattern
  1491.     dc.w    $4E7B,$1006    ; movec d1,(006) DTT0
  1492.     dc.w    $4E7B,$1007    ; movec d1,(007) DTT1
  1493.  
  1494.     andi.w    #$D8FF,sr    ; ints on & user mode
  1495.     moveq    #0,d0
  1496.     rts
  1497.  
  1498. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1499. DMODE:
  1500.     cmp.l    a3,a5
  1501.     bne    RPRT_BP
  1502.  
  1503.     moveq    #-1,d1
  1504.     moveq    #-1,d2
  1505.     moveq    #MT.DMODE,d0
  1506.     trap    #1
  1507.  
  1508.     bra    RET_W
  1509.  
  1510. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1511.     ifd    extras
  1512.  
  1513. B_INTENR:
  1514.     move.w    INTENAR,d1
  1515.     bra    RET_W
  1516.  
  1517. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1518. B_INTRQR:
  1519.     move.w    INTREQR,d1
  1520.     bra    RET_W
  1521.  
  1522. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1523. B_DMACNR:
  1524.     move.w    DMACONR,d1
  1525.     bra    RET_W
  1526.  
  1527. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1528. B_CHIP:
  1529.     trap    #0
  1530.     ori.w    #$0700,sr
  1531.  
  1532.     move.l    a7,d0
  1533.     andi.l    #$FFFF8000,d0
  1534.     move.l    d0,a0        ; address of system vars
  1535.  
  1536.     move.l    SV_RAMT(a0),a3    ; limit for RAM check
  1537.  
  1538.     bsr    chip_ram
  1539.  
  1540.     andi.w    #$D8FF,sr
  1541.     move.l    a2,d1
  1542.     bra    RET_L
  1543.  
  1544. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1545. B_EXPANSION:
  1546.     trap    #0
  1547.     ori.w    #$0700,sr
  1548.  
  1549.     move.l    a7,d0
  1550.     andi.l    #$FFFF8000,d0
  1551.     move.l    d0,a0        ; address of system vars
  1552.  
  1553.     lea    $200000,a1    ; RAM check start address
  1554.     move.l    SV_RAMT(a0),a3    ; limit for RAM check
  1555.  
  1556.     bsr    expansion_ram
  1557.  
  1558.     andi.w    #$D8FF,sr
  1559.     move.l    a2,d1
  1560.     bra    RET_L
  1561.  
  1562. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1563. B_RANGER:
  1564.     trap    #0
  1565.     ori.w    #$0700,sr
  1566.  
  1567.     move.l    a7,d0
  1568.     andi.l    #$FFFF8000,d0
  1569.     move.l    d0,a0        ; address of system vars
  1570.  
  1571.     move.l    SV_RAMT(a0),a3    ; limit for RAM check
  1572.  
  1573.     bsr    ranger_ram
  1574.  
  1575.     andi.w    #$D8FF,sr
  1576.     move.l    a2,d1
  1577.     bra    RET_L
  1578.  
  1579.     endc
  1580.  
  1581. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1582. ; Entry: A3.L   pointer to first parameter
  1583. ;    A5.L   pointer to last parameter
  1584. ;
  1585. ; Exit:    A3.L   updated
  1586. ;    A5.L   updated
  1587. ;    D0.L...error code
  1588. ;    D1.W   result
  1589.  
  1590. FETCH_W:
  1591.     MOVEM.L    A1-A2,-(A7)
  1592.  
  1593.     MOVE.W    CA.GTINT,A2
  1594.     BSR.S    GET_ONE
  1595.     BNE.S    FETCH_WX
  1596.  
  1597.     MOVE.W    #0,D1
  1598.     MOVE.W    0(A6,A1.L),D1
  1599.     ADDQ.L    #2,A1
  1600.     MOVE.L    A1,BV_RIP(A6)
  1601.  
  1602. FETCH_WX:
  1603.     MOVEM.L    (A7)+,A1-A2
  1604.     TST.L    D0
  1605.     RTS
  1606.  
  1607. ; --------------------------------------------------------------
  1608. ; Fetch one long word
  1609.  
  1610. FETCH_L:
  1611.     movem.l    a2,-(a7)
  1612.  
  1613.     move.w    CA.GTLIN,a2
  1614.     bsr.s    GET_ONE
  1615.     bne.s    FETCH_LX
  1616.  
  1617.     move.l    a1,BV_RIP(a6)
  1618.     move.l    0(a6,a1.l),d1
  1619.     addq.l    #4,BV_RIP(a6)
  1620.  
  1621. FETCH_LX:
  1622.     movem.l    (a7)+,a2
  1623.     tst.l    d0
  1624.     rts
  1625.  
  1626. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1627. ;  This routine gets one parameter and returns it on the maths
  1628. ;  stack, pointed to by (A1).
  1629. ;
  1630. ; Entry: A2.L   routine to call (i.e. CA.GTINT)
  1631. ;    A3.L   pointer to first parameter
  1632. ;    A5.L   pointer to last parameter
  1633. ;
  1634. ; Exit:    A3.L   updated
  1635. ;    A5.L   updated
  1636. ;    A1.L   updated pointer to top of maths stack
  1637. ;    D0.L   error code
  1638.  
  1639. GET_ONE:
  1640.     MOVEM.L    D1-D6/A0/A2,-(A7)
  1641.  
  1642.     LEA    8(A3),A0
  1643.     CMP.L    A0,A5
  1644.     BLT.S    GET_ONEBp
  1645.  
  1646.     MOVE.L    BV_RIP(A6),A1
  1647.     MOVE.L    A5,-(A7)
  1648.     MOVE.L    A0,A5
  1649.     MOVE.L    A5,-(A7)
  1650.     JSR    (A2)
  1651.     MOVEM.L    (A7)+,A0/A5
  1652.  
  1653.     TST.L    D0
  1654.     BNE.S    GET_ONEX
  1655.  
  1656.     MOVE.L    A0,A3
  1657.     MOVE.L    A1,BV_RIP(A6)
  1658.  
  1659.     BRA.S    GET_ONEX
  1660.  
  1661. GET_ONEBp:
  1662.     MOVEQ    #ERR.BP,D0
  1663.  
  1664. GET_ONEX:
  1665.     MOVEM.L    (A7)+,D1-D6/A0/A2
  1666.     TST.L    D0
  1667.     RTS
  1668.  
  1669. ; --------------------------------------------------------------
  1670. ;  Return word d1.w to BASIC
  1671.  
  1672. RET_W:
  1673.     move.l    d1,d4
  1674.     moveq.l    #2,d1
  1675.     move.w    BV.CHRIX,a2
  1676.     jsr    (a2)
  1677.     move.l    d4,d1
  1678.  
  1679.     move.l    BV_RIP(a6),a1    ; Get arith stack pointer
  1680.     subq.l    #2,a1        ; room for 2 bytes
  1681.     move.l    a1,BV_RIP(a6)
  1682.     move.w    d1,0(a6,a1.l)    ; Put int number on stack
  1683.     moveq.l    #3,d4        ; set Integer type
  1684.  
  1685.     moveq.l    #ERR.OK,d0    ; no errors
  1686.     rts
  1687.  
  1688. ; -------------------------------------------------------------
  1689. ;    Return long Integer d1.l to BASIC
  1690.  
  1691. RET_L:
  1692.     move.l    d1,d4
  1693.     moveq.l    #6,d1
  1694.     move.w    BV.CHRIX,a2
  1695.     jsr    (a2)
  1696.     move.l    d4,d1
  1697.  
  1698.     bsr.s    CONV_L2F
  1699.     subq.l    #6,BV_RIP(a6)
  1700.     move.l    BV_RIP(a6),a1
  1701.     move.w    d2,0(a6,a1.l)
  1702.     move.l    d1,2(a6,a1.l)
  1703.     moveq.l    #2,d4
  1704.  
  1705.     moveq.l    #ERR.OK,d0
  1706.     rts
  1707.  
  1708. ; -------------------------------------------------------------
  1709. ;  convert long Integer to floating point form.
  1710. ;  Entry: d1.l = long int
  1711. ;  Exit:  d1.w = mantissa
  1712. ;     d2.l = exponent
  1713.  
  1714. CONV_L2F:
  1715.     move.l    d1,d2
  1716.     beq.s    CONV_L2FX
  1717.  
  1718.     move.w    #$81F,d2
  1719.     move.l    d1,-(a7)
  1720.  
  1721. CONV_L2F1:
  1722.     add.l    d1,d1
  1723.     bvs.s    CONV_L2F2
  1724.  
  1725.     subq.w    #1,d2
  1726.     move.l    d1,(a7)
  1727.     bra.s    CONV_L2F1
  1728.  
  1729. CONV_L2F2:
  1730.     move.l    (a7)+,d1
  1731.  
  1732. CONV_L2FX:
  1733.     rts
  1734.  
  1735. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1736. RPRT_BP:
  1737.     moveq    #ERR.BP,d0
  1738.     rts
  1739.  
  1740. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1741.     END
  1742.